package com.lll.handler;

import com.lll.config.Config;
import com.lll.constants.ProtocolConstants;
import com.lll.protocol.Message;
import com.lll.protocol.MessageHeader;
import com.lll.serialization.Serialization;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;

import java.util.List;

public class MessageCodec extends ByteToMessageCodec<Message<Object>> {
    @Override
    public void encode(ChannelHandlerContext channelHandlerContext, Message<Object> objectMessage, ByteBuf byteBuf) throws Exception {
        // 获取消息头 消息体
        MessageHeader header = objectMessage.getHeader();
        Object body = objectMessage.getBody();
        byteBuf.writeByte(header.getMagicNumber());
        byteBuf.writeByte(header.getVersion());
        byteBuf.writeByte(header.getSerializationType());
        byteBuf.writeByte(header.getType());
        byteBuf.writeLong(header.getSequenceId());
        // body长度和body
        Serialization.Algorithm serialization = Config.getSerializerAlgorithm(header.getSerializationType());
        byte[] byteBody = serialization.serialize(body);
        byteBuf.writeInt(byteBody.length);
        byteBuf.writeBytes(byteBody);

    }

    @Override
    public void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        byte magicNumber = byteBuf.readByte();
        if (magicNumber != ProtocolConstants.MAGIC_NUMBER) {
            throw new IllegalArgumentException("magic number is illegal, " + magicNumber);
        }
        byte version = byteBuf.readByte();
        byte serialType = byteBuf.readByte();
        byte type = byteBuf.readByte();
        long sequenceId = byteBuf.readLong();
        int length = byteBuf.readInt();
        byte[] body = new byte[length];
        // 读取到body数组
        byteBuf.readBytes(body);


        MessageHeader header = new MessageHeader();
        header.setMagicNumber(magicNumber);
        header.setVersion(version);
        header.setType(type);
        header.setSerializationType(serialType);
        header.setLength(length);
        header.setSequenceId(sequenceId);
        // 反序列化
        Serialization.Algorithm algorithm = Config.getSerializerAlgorithm(serialType);
        Object bodyObj = algorithm.deserialize(Message.getMessageClass(type), body);

        Message message = new Message();
        message.setHeader(header);
        message.setBody(body);
        list.add(message);


    }
}
